package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.constant.RobotName;
import cn.com.acca.ma.model.HistoryRobotAccountLog;
import cn.com.acca.ma.model.Model;
import cn.com.acca.ma.pojo.SuccessRateOrPercentagePojo;
import cn.com.acca.ma.service.ModelService;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class ModelServiceImpl extends BaseServiceImpl<ModelServiceImpl, Model> implements ModelService {

    @SuppressWarnings("rawtypes")
    @Override
    public String listToString(List list) {
        return null;
    }

    /**
     * 将所有交易策略金叉成功率和收盘价绘制在一张折线图上
     *
     * @param multithreading
     */
    @Override
    public void createAllTransactionStrategyGoldCrossSuccessRatePicture(boolean multithreading) {
        String beginDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.gold.cross.success.rate.begin_date");
        String endDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.gold.cross.success.rate.end_date");
        Integer dateNumber = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.gold.cross.success.rate.date_number"));

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("股票收盘价", org.jfree.data.time.Day.class);
        TimeSeries macdGoldCrossSuccessRateSeries = new TimeSeries("MACD金叉交易策略的成功率", org.jfree.data.time.Day.class);
        TimeSeries closePriceGlodCrossMa5SuccessRateSeries = new TimeSeries("收盘价金叉MA5交易策略的成功率", org.jfree.data.time.Day.class);
        TimeSeries heiKinAshiUpDownSuccessRateSeries = new TimeSeries("hei_kin_ashi上涨趋势交易策略的成功率", org.jfree.data.time.Day.class);
        TimeSeries kdGoldCrossSuccessRateSeries = new TimeSeries("kd金叉交易策略的成功率", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<SuccessRateOrPercentagePojo> macdGoldCrossSuccessRateList = modelMACDGoldCrossDao.getMACDGoldCrossSuccessRate(multithreading, beginDate, endDate, dateNumber * 2);
        List<SuccessRateOrPercentagePojo> closePriceMa5SuccessRateList = modelClosePriceMA5GoldCrossDao.getClosePriceMa5GoldCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);
        List<SuccessRateOrPercentagePojo> heiKinAshiUpDownSuccessRateList = modelHeiKinAshiUpDownDao.getHeiKinAshiUpDownSuccessRate(multithreading, beginDate, endDate, dateNumber);
        List<SuccessRateOrPercentagePojo> kdGoldCrossSuccessRateList = modelKDGoldCrossDao.getKdGoldCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);

        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.addOrUpdate(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < macdGoldCrossSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date macdGoldCrossSuccessRateListDate = ((SuccessRateOrPercentagePojo) macdGoldCrossSuccessRateList.get(j)).getTransactionDate();

            if (averageAllCloseListDate.equals(macdGoldCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(((SuccessRateOrPercentagePojo) macdGoldCrossSuccessRateList.get(j)).getSuccessRateOrPercentage().toString());
                macdGoldCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(macdGoldCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdGoldCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdGoldCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(macdGoldCrossSuccessRateSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < closePriceMa5SuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date closePriceMa5SuccessRateListDate = ((SuccessRateOrPercentagePojo) closePriceMa5SuccessRateList.get(j)).getTransactionDate();

            if (averageAllCloseListDate.equals(closePriceMa5SuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(((SuccessRateOrPercentagePojo) closePriceMa5SuccessRateList.get(j)).getSuccessRateOrPercentage().toString());
                closePriceGlodCrossMa5SuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(closePriceMa5SuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceGlodCrossMa5SuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceGlodCrossMa5SuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(closePriceGlodCrossMa5SuccessRateSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < heiKinAshiUpDownSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date heiKinAshiUpDownSuccessRateListDate = (Date) ((SuccessRateOrPercentagePojo) heiKinAshiUpDownSuccessRateList.get(j)).getTransactionDate();

            if (averageAllCloseListDate.equals(heiKinAshiUpDownSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(((SuccessRateOrPercentagePojo) heiKinAshiUpDownSuccessRateList.get(j)).getSuccessRateOrPercentage().toString());
                heiKinAshiUpDownSuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(heiKinAshiUpDownSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiUpDownSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiUpDownSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(heiKinAshiUpDownSuccessRateSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < kdGoldCrossSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date kdGoldCrossSuccessRateListDate = kdGoldCrossSuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(kdGoldCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(((SuccessRateOrPercentagePojo) kdGoldCrossSuccessRateList.get(j)).getSuccessRateOrPercentage().toString());
                kdGoldCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(kdGoldCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdGoldCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdGoldCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(kdGoldCrossSuccessRateSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("所有金叉交易策略的成功率",
                "时间", "成功率", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "all_transaction_strategy_gold_cross_success_rate/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将所有交易策略死叉成功率和收盘价绘制在一张折线图上
     *
     * @param multithreading
     */
    @Override
    public void createAllTransactionStrategyDeadCrossSuccessRatePicture(boolean multithreading) {
        String beginDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.dead.cross.success.rate.begin_date");
        String endDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.dead.cross.success.rate.end_date");
        Integer dateNumber = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.dead.cross.success.rate.date_number"));

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("股票收盘价", org.jfree.data.time.Day.class);
        TimeSeries macdDeadCrossSuccessRateSeries = new TimeSeries("MACD死叉交易策略的成功率", org.jfree.data.time.Day.class);
        TimeSeries closePriceDeadCrossMa5SuccessRateSeries = new TimeSeries("收盘价死叉MA5交易策略的成功率", org.jfree.data.time.Day.class);
        TimeSeries heiKinAshiDownUpSuccessRateSeries = new TimeSeries("hei_kin_ashi下跌趋势交易策略的成功率", org.jfree.data.time.Day.class);
        TimeSeries kdDeadCrossSuccessRateSeries = new TimeSeries("kd死叉交易策略的成功率", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<SuccessRateOrPercentagePojo> macdDeadCrossSuccessRateList = modelMACDDeadCrossDao.getMACDDeadCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);
        List<SuccessRateOrPercentagePojo> closePriceDeadCrossMa5SuccessRateList = modelClosePriceMA5DeadCrossDao.getClosePriceMa5DeadCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);
        List<SuccessRateOrPercentagePojo> heiKinAshiDownUpSuccessRateList = modelHeiKinAshiDownUpDao.getHeiKinAshiDownUpSuccessRate(multithreading, beginDate, endDate, dateNumber);
        List<SuccessRateOrPercentagePojo> kdDeadCrossSuccessRateList = modelKDDeadCrossDao.getKdDeadCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);

        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.addOrUpdate(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < macdDeadCrossSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date macdDeadCrossSuccessRateListDate = macdDeadCrossSuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(macdDeadCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(macdDeadCrossSuccessRateList.get(j).getSuccessRateOrPercentage().toString());
                macdDeadCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(macdDeadCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdDeadCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdDeadCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(macdDeadCrossSuccessRateSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < closePriceDeadCrossMa5SuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date closePriceDeadCrossMa5SuccessRateListDate = closePriceDeadCrossMa5SuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(closePriceDeadCrossMa5SuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(closePriceDeadCrossMa5SuccessRateList.get(j).getSuccessRateOrPercentage().toString());
                closePriceDeadCrossMa5SuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(closePriceDeadCrossMa5SuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceDeadCrossMa5SuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceDeadCrossMa5SuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(closePriceDeadCrossMa5SuccessRateSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < heiKinAshiDownUpSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date heiKinAshiDownUpSuccessRateListDate = heiKinAshiDownUpSuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(heiKinAshiDownUpSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(heiKinAshiDownUpSuccessRateList.get(j).getSuccessRateOrPercentage().toString());
                heiKinAshiDownUpSuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(heiKinAshiDownUpSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiDownUpSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiDownUpSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(heiKinAshiDownUpSuccessRateSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < kdDeadCrossSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date kdDeadCrossSuccessRateListDate = kdDeadCrossSuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(kdDeadCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(kdDeadCrossSuccessRateList.get(j).getSuccessRateOrPercentage().toString());
                kdDeadCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(kdDeadCrossSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdDeadCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdDeadCrossSuccessRateSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(kdDeadCrossSuccessRateSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("所有死叉交易策略的成功率",
                "时间", "成功率", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "all_transaction_strategy_dead_cross_success_rate/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将所有交易策略金叉百分比和收盘价绘制在一张折线图上
     *
     * @param multithreading
     */
    @Override
    public void createAllTransactionStrategyGoldCrossPercentagePicture(boolean multithreading) {
        String beginDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.gold.cross.percentage.begin_date");
        String endDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.gold.cross.percentage.end_date");

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("百分比", org.jfree.data.time.Day.class);
        TimeSeries macdGoldCrossPercentageSeries = new TimeSeries("MACD金叉的百分比", org.jfree.data.time.Day.class);
        TimeSeries closePriceGoldCrossMa5PercentageSeries = new TimeSeries("收盘价金叉MA5交易策略的百分比", org.jfree.data.time.Day.class);
        TimeSeries heiKinAshiUpDownPercentageSeries = new TimeSeries("hei_kin_ashi上涨趋势交易策略的百分比", org.jfree.data.time.Day.class);
        TimeSeries kdGoldCrossPercentageSeries = new TimeSeries("kd金叉交易策略的百分比", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<SuccessRateOrPercentagePojo> macdGoldCrossPercentageList = modelMACDGoldCrossDao.getMACDGoldCrossPercentage(multithreading, beginDate, endDate);
        List<SuccessRateOrPercentagePojo> closePriceMa5PercentageList = modelClosePriceMA5GoldCrossDao.getClosePriceMa5GoldCrossPercentage(multithreading, beginDate, endDate);
        List<SuccessRateOrPercentagePojo> heiKinAshiUpDownPercentageList = modelHeiKinAshiUpDownDao.getHeiKinAshiUpDownPercentage(multithreading, beginDate, endDate);
        List<SuccessRateOrPercentagePojo> kdGoldCrossPercentageList = modelKDGoldCrossDao.getKdGoldCrossPercentage(multithreading, beginDate, endDate);

        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.addOrUpdate(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < macdGoldCrossPercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date macdGoldCrossPercentageListDate = macdGoldCrossPercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(macdGoldCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(macdGoldCrossPercentageList.get(j).getSuccessRateOrPercentage().toString());
                macdGoldCrossPercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(macdGoldCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdGoldCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdGoldCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(macdGoldCrossPercentageSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < closePriceMa5PercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date closePriceMa5PercentageListDate = closePriceMa5PercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(closePriceMa5PercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(closePriceMa5PercentageList.get(j).getSuccessRateOrPercentage().toString());
                closePriceGoldCrossMa5PercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(closePriceMa5PercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceGoldCrossMa5PercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceGoldCrossMa5PercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(closePriceGoldCrossMa5PercentageSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < heiKinAshiUpDownPercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date heiKinAshiUpDownPercentageListDate = heiKinAshiUpDownPercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(heiKinAshiUpDownPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(heiKinAshiUpDownPercentageList.get(j).getSuccessRateOrPercentage().toString());
                heiKinAshiUpDownPercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(heiKinAshiUpDownPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiUpDownPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiUpDownPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(heiKinAshiUpDownPercentageSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < kdGoldCrossPercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date kdGoldCrossPercentageListDate = kdGoldCrossPercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(kdGoldCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(kdGoldCrossPercentageList.get(j).getSuccessRateOrPercentage().toString());
                kdGoldCrossPercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(kdGoldCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdGoldCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdGoldCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(kdGoldCrossPercentageSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("所有股票金叉的百分比",
                "时间", "百分比", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "all_transaction_strategy_gold_cross_percentage/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将所有交易策略死叉百分比和收盘价绘制在一张折线图上
     *
     * @param multithreading
     */
    @Override
    public void createAllTransactionStrategyDeadCrossPercentagePicture(boolean multithreading) {
        String beginDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.dead.cross.percentage.begin_date");
        String endDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "all.transaction.strategy.dead.cross.percentage.end_date");

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("百分比", org.jfree.data.time.Day.class);
        TimeSeries macdDeadCrossPercentageSeries = new TimeSeries("MACD死叉的百分比", org.jfree.data.time.Day.class);
        TimeSeries closePriceDeadCrossMa5PercentageSeries = new TimeSeries("收盘价死叉MA5交易策略的百分比", org.jfree.data.time.Day.class);
        TimeSeries heiKinAshiDownUpPercentageSeries = new TimeSeries("hei_kin_ashi下跌趋势交易策略的百分比", org.jfree.data.time.Day.class);
        TimeSeries kdDeadCrossPercentageSeries = new TimeSeries("kd死叉交易策略的百分比", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<SuccessRateOrPercentagePojo> macdDeadCrossPercentageList = modelMACDDeadCrossDao.getMACDDeadCrossPercentage(multithreading, beginDate, endDate);
        List<SuccessRateOrPercentagePojo> closePriceDeadCrossMa5PercentageList = modelClosePriceMA5DeadCrossDao.getClosePriceMa5DeadCrossPercentage(multithreading, beginDate, endDate);
        List<SuccessRateOrPercentagePojo> heiKinAshiDownUpPercentageList = modelHeiKinAshiDownUpDao.getHeiKinAshiDownUpPercentage(multithreading, beginDate, endDate);
        List<SuccessRateOrPercentagePojo> kdDeadCrossPercentageList = modelKDDeadCrossDao.getKdDeadCrossPercentage(multithreading, beginDate, endDate);

        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.addOrUpdate(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < macdDeadCrossPercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date macdDeadCrossPercentageListDate = macdDeadCrossPercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(macdDeadCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(macdDeadCrossPercentageList.get(j).getSuccessRateOrPercentage().toString());
                macdDeadCrossPercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(macdDeadCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdDeadCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdDeadCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(macdDeadCrossPercentageSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < closePriceDeadCrossMa5PercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date closePriceDeadCrossMa5PercentageListDate = closePriceDeadCrossMa5PercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(closePriceDeadCrossMa5PercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(closePriceDeadCrossMa5PercentageList.get(j).getSuccessRateOrPercentage().toString());
                closePriceDeadCrossMa5PercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(closePriceDeadCrossMa5PercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceDeadCrossMa5PercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                closePriceDeadCrossMa5PercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(closePriceDeadCrossMa5PercentageSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < heiKinAshiDownUpPercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date heiKinAshiDownUpPercentageListDate = heiKinAshiDownUpPercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(heiKinAshiDownUpPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(heiKinAshiDownUpPercentageList.get(j).getSuccessRateOrPercentage().toString());
                heiKinAshiDownUpPercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(heiKinAshiDownUpPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiDownUpPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiKinAshiDownUpPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(heiKinAshiDownUpPercentageSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < kdDeadCrossPercentageList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date kdDeadCrossPercentageListDate = kdDeadCrossPercentageList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(kdDeadCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(kdDeadCrossPercentageList.get(j).getSuccessRateOrPercentage().toString());
                kdDeadCrossPercentageSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(kdDeadCrossPercentageListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdDeadCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                kdDeadCrossPercentageSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(kdDeadCrossPercentageSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("所有股票死叉的百分比",
                "时间", "百分比", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "all_transaction_strategy_dead_cross_percentage/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从robot开头的表，将测试数据导入到HIS_开头的表中。如果被错误地执行了多次也没事
     */
    @Override
    public void importIntoHistoryDataTableFromRobot() {
        Integer initAssets = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.init.assets"));
        Integer modelId = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.modelId"));

        // 获取最新的模型
//        List<Model> modelList = modelDao.orderById();

        // 删除TEMP_开头的表
        modelDao.dropTableBeginWithTemp();

        // 将ROBOT_开头的表中的记录导入到TEMP_开头的表中
        modelDao.importIntoTableBeginWithTempFromTableBeginWithRobot();

        // 将TEMP_开头的表导入到HIS_开头的表中
        modelDao.insertIntoTableBeginWithHisFromTableBeginWithTemp(modelId);

        // 删除或重置ROBOT_开头的表中的记录
        modelDao.truncateOrResetTableBeginRobot(initAssets);
    }

    /**
     * 从robot2开头的表，将测试数据导入到HIS_开头的表中。如果被错误地执行了多次也没事
     */
    @Override
    public void importIntoHistoryDataTableFromRobot2() {
        Integer initAssets = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.averageGoldCrossDeadCross.init.assets"));
        Integer modelId = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.averageGoldCrossDeadCross.modelId"));

        // 获取最新的模型
//        List<Model> modelList = modelDao.orderById();

        // 删除TEMP_开头的表
        modelDao.dropTableBeginWithTemp();

        // 将ROBOT2_开头的表中的记录导入到TEMP_开头的表中
        modelDao.importIntoTableBeginWithTempFromTableBeginWithRobot2();

        // 将TEMP_开头的表导入到HIS_开头的表中
        modelDao.insertIntoTableBeginWithHisFromTableBeginWithTemp(modelId);

        // 删除或重置ROBOT2_开头的表中的记录
        modelDao.truncateOrResetTableBeginRobot2(initAssets);
    }

    /**
     * 从robot3开头的表，将测试数据导入到HIS_开头的表中。如果被错误地执行了多次也没事
     */
    @Override
    public void importIntoHistoryDataTableFromRobot3() {
        Integer initAssets = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.week.boll.init.assets"));
        Integer modelId = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.week.boll.modelId"));

        // 获取最新的模型
//        List<Model> modelList = modelDao.orderById();

        // 删除TEMP_开头的表
        modelDao.dropTableBeginWithTemp();

        // 将ROBOT3_开头的表中的记录导入到TEMP_开头的表中
        modelDao.importIntoTableBeginWithTempFromTableBeginWithRobot3();

        // 将TEMP_开头的表导入到HIS_开头的表中
        modelDao.insertIntoTableBeginWithHisFromTableBeginWithTemp(modelId);

        // 删除或重置ROBOT3_开头的表中的记录
        modelDao.truncateOrResetTableBeginRobot3(initAssets);
    }

    /**
     * 从robot4开头的表，将测试数据导入到HIS_开头的表中。如果被错误地执行了多次也没事
     */
    @Override
    public void importIntoHistoryDataTableFromRobot4() {
        Integer initAssets = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.week.kd.init.assets"));
        Integer modelId = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.week.kd.modelId"));

        // 获取最新的模型
        List<Model> modelList = modelDao.orderById();

        // 删除TEMP_开头的表
        modelDao.dropTableBeginWithTemp();

        // 将ROBOT4_开头的表中的记录导入到TEMP_开头的表中
        modelDao.importIntoTableBeginWithTempFromTableBeginWithRobot4();

        // 将TEMP_开头的表导入到HIS_开头的表中
        modelDao.insertIntoTableBeginWithHisFromTableBeginWithTemp(modelId);

        // 删除或重置ROBOT4_开头的表中的记录
        modelDao.truncateOrResetTableBeginRobot4(initAssets);
    }

    /**
     * 从robot5开头的表，将测试数据导入到HIS_开头的表中。如果被错误地执行了多次也没事
     */
    @Override
    public void importIntoHistoryDataTableFromRobot5() {
        Integer initAssets = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.multipleMethod.init.assets"));
        Integer modelId = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.multipleMethod.modelId"));

        // 获取最新的模型
        List<Model> modelList = modelDao.orderById();

        // 删除TEMP_开头的表
        modelDao.dropTableBeginWithTemp();

        // 将ROBOT5_开头的表中的记录导入到TEMP_开头的表中
        modelDao.importIntoTableBeginWithTempFromTableBeginWithRobot5();

        // 将TEMP_开头的表导入到HIS_开头的表中
        modelDao.insertIntoTableBeginWithHisFromTableBeginWithTemp(modelId);

        // 删除或重置ROBOT4_开头的表中的记录
        modelDao.truncateOrResetTableBeginRobot5(initAssets);
    }

    /**
     * 从robot6开头的表，将测试数据导入到HIS_开头的表中。如果被错误地执行了多次也没事
     */
    @Override
    public void importIntoHistoryDataTableFromRobot6() {
        Integer initAssets = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.etf12YearHighestAverageProfitRate.init.assets"));
        Integer modelId = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.buy.sell.etf12YearHighestAverageProfitRate.modelId"));

        // 获取最新的模型
//        List<Model> modelList = modelDao.orderById();

        // 删除TEMP_开头的表
        modelDao.dropTableBeginWithTemp();

        // 将ROBOT6_开头的表中的记录导入到TEMP_开头的表中
        modelDao.importIntoTableBeginWithTempFromTableBeginWithRobot6();

        // 将TEMP_开头的表导入到HIS_开头的表中
        modelDao.insertIntoTableBeginWithHisFromTableBeginWithTemp(modelId);

        // 删除或重置ROBOT6_开头的表中的记录
        modelDao.truncateOrResetTableBeginRobot6(initAssets);
    }

    /**
     * 创建机器人账户的收益率图表
     * @param multithreading
     */
    @Override
    public void createRobotAccountLogProfitRatePicture(boolean multithreading) {
        String beginDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.account.log.profit.rate.begin_date");
        String endDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.account.log.profit.rate.end_date");
        Integer modelId = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.account.log.profit.rate.modelId"));
        Integer initAssets = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.account.log.profit.rate.init.assets"));
        String[] robotNameArray = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.account.log.profit.rate.robotNameList")
                .replace(" ", "").replaceAll("\\[", "").replace("]", "").split(",");

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("平均收盘价", org.jfree.data.time.Day.class);
        TimeSeries lanJingLingTimeSeries = new TimeSeries(RobotName.LAN_JING_LING + "收益率", org.jfree.data.time.Day.class);
        TimeSeries geGeWuTimeSeries = new TimeSeries(RobotName.GE_GE_WU + "收益率", org.jfree.data.time.Day.class);
        TimeSeries heiMaoJingZhangTimeSeries = new TimeSeries(RobotName.HEI_MAO_JING_ZHANG + "收益率", org.jfree.data.time.Day.class);
        TimeSeries yiZhiErTimeSeries = new TimeSeries(RobotName.YI_ZHI_ER + "收益率", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<HistoryRobotAccountLog> lanJingLingHistoryRobotAccountLogList = historyRobotAccountLogDao.findByDateBetweenAndRobotNameAndModelIdOrderByDateAsc(beginDate, endDate, robotNameArray[0], modelId, initAssets);
        List<HistoryRobotAccountLog> geGeWuHistoryRobotAccountLogList = historyRobotAccountLogDao.findByDateBetweenAndRobotNameAndModelIdOrderByDateAsc(beginDate, endDate, robotNameArray[1], modelId, initAssets);
        List<HistoryRobotAccountLog> heiMaoJingZhangHistoryRobotAccountLogList = historyRobotAccountLogDao.findByDateBetweenAndRobotNameAndModelIdOrderByDateAsc(beginDate, endDate, robotNameArray[2], modelId, initAssets);
        List<HistoryRobotAccountLog> yiZhiErHistoryRobotAccountLogList = historyRobotAccountLogDao.findByDateBetweenAndRobotNameAndModelIdOrderByDateAsc(beginDate, endDate, robotNameArray[3], modelId, initAssets);
        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.addOrUpdate(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < lanJingLingHistoryRobotAccountLogList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date lanJingLingHistoryRobotAccountLogDate = lanJingLingHistoryRobotAccountLogList.get(j).getDate_();

            if (averageAllCloseListDate.equals(lanJingLingHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(lanJingLingHistoryRobotAccountLogList.get(j).getProfitRate().toString());
                lanJingLingTimeSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(lanJingLingHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                lanJingLingTimeSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                lanJingLingTimeSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(lanJingLingTimeSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < geGeWuHistoryRobotAccountLogList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date geGeWuHistoryRobotAccountLogDate = geGeWuHistoryRobotAccountLogList.get(j).getDate_();

            if (averageAllCloseListDate.equals(geGeWuHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(geGeWuHistoryRobotAccountLogList.get(j).getProfitRate().toString());
                geGeWuTimeSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(geGeWuHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                geGeWuTimeSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                geGeWuTimeSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(geGeWuTimeSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < heiMaoJingZhangHistoryRobotAccountLogList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date heiMaoJingZhangHistoryRobotAccountLogDate = heiMaoJingZhangHistoryRobotAccountLogList.get(j).getDate_();

            if (averageAllCloseListDate.equals(heiMaoJingZhangHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(heiMaoJingZhangHistoryRobotAccountLogList.get(j).getProfitRate().toString());
                heiMaoJingZhangTimeSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(heiMaoJingZhangHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiMaoJingZhangTimeSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                heiMaoJingZhangTimeSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(heiMaoJingZhangTimeSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < yiZhiErHistoryRobotAccountLogList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date yiZhiErHistoryRobotAccountLogDate = yiZhiErHistoryRobotAccountLogList.get(j).getDate_();

            if (averageAllCloseListDate.equals(yiZhiErHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(yiZhiErHistoryRobotAccountLogList.get(j).getProfitRate().toString());
                yiZhiErTimeSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(yiZhiErHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                yiZhiErTimeSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                yiZhiErTimeSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(yiZhiErTimeSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("所有机器人账号收益率的百分比",
                "时间", "百分比", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "robot_name_profit_rate/" + modelId + "_" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建机器人账户（ETF）的收益率图表
     * @param multithreading
     */
    @Override
    public void createRobotEtfAccountLogProfitRatePicture(boolean multithreading) {
        String beginDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.etf.account.log.profit.rate.begin_date");
        String endDate = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.etf.account.log.profit.rate.end_date");
        Integer modelId = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.etf.account.log.profit.rate.modelId"));
        Integer initAssets = Integer.parseInt(PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.etf.account.log.profit.rate.init.assets"));
        String[] robotNameArray = PropertiesUtil
                .getValue(MODEL_PICTURE_PROPERTIES, "robot.etf.account.log.profit.rate.robotNameList")
                .replace(" ", "").replaceAll("\\[", "").replace("]", "").split(",");

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("平均收盘价", org.jfree.data.time.Day.class);
        TimeSeries etfTimeSeries = new TimeSeries("收益率", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = etfTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = etfTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate);
        List<HistoryRobotAccountLog> etfHistoryRobotAccountLogList = historyRobotAccountLogDao.findByDateBetweenAndRobotNameAndModelIdOrderByDateAsc(beginDate, endDate, robotNameArray[0], modelId, initAssets);
        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.addOrUpdate(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < etfHistoryRobotAccountLogList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date lanJingLingHistoryRobotAccountLogDate = etfHistoryRobotAccountLogList.get(j).getDate_();

            if (averageAllCloseListDate.equals(lanJingLingHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(etfHistoryRobotAccountLogList.get(j).getProfitRate().toString());
                etfTimeSeries.addOrUpdate(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(lanJingLingHistoryRobotAccountLogDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                etfTimeSeries.addOrUpdate(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                etfTimeSeries.addOrUpdate(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(etfTimeSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("机器人账号收益率的百分比",
                "时间", "百分比", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "robot_etf_name_profit_rate/" + modelId + "_" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
